package org.nerve.tinker.rpc.component;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.nerve.tinker.rpc.TinkerService;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

/**
 * com.zeus.sndp.collector.rpc
 * Created by zengxm on 2016/4/24 0024.
 */
public abstract class CommonRpcServer<T extends TinkerService.Iface> {
	public static final String HOST = "rpc.host";
	public static final String PORT = "rpc.port";

	private final String host;
	private int port;
	TServer server;

	protected abstract T getServiceImpl();

	public CommonRpcServer(){
		this.host=loadHost();
		this.port=loadPort();
	}

	public CommonRpcServer(String h,int p){
		this.host=h;
		this.port=p;
	}

	/**
	 * 增加默认Host功能，从系统配置中读取rpc.host，如果不为空则使用该值作为RPC其中的Host
	 * @return
	 */
	private String loadHost(){
		try {
			String rpcHost = System.getProperty(HOST);
			return rpcHost==null? InetAddress.getLocalHost().getHostAddress():rpcHost;
		} catch (UnknownHostException e) {
			return "localhost";
		}
	}

	/**
	 * 从系统配置中读取rpc.port，如果不为空则使用该值作为RPC其中的Port
	 * @return
	 */
	private int loadPort(){
		try{
			String rpcPort=System.getProperty(PORT);
			return rpcPort==null?9090:Integer.valueOf(rpcPort);
		}catch (Exception e){
			return 9090;
		}
	}

	/**
	 * 启动RPC
	 */
	public void startup() throws TTransportException {
		TProcessor processor = new TinkerService.Processor<TinkerService.Iface>(getServiceImpl());
		TNonblockingServerSocket tSocketTranport = new TNonblockingServerSocket(
				new InetSocketAddress(host, port));

		TNonblockingServer.Args targs = new TNonblockingServer.Args(
				tSocketTranport);

		targs.protocolFactory(new TCompactProtocol.Factory());
		targs.processor(processor);

		server= new TNonblockingServer(targs);
		System.out.println("startup RPC Server on "+host+":"+port+"......");
		server.serve();
	}

	public void stop(){
		if(server!=null && server.isServing())
			server.stop();
	}

	public String getHost() {
		return host;
	}

	public int getPort() {
		return port;
	}
}
